package com.sali.controller;

import com.sali.pojo.entity.Stock;
import com.sali.pojo.vo.StockVO;
import com.sali.service.IStockOrderService;
import com.sali.utils.loadbalance.ILoadBalanceAlgorithm;
import com.sali.utils.loadbalance.SmoothWeightedRoundRobin;
import com.sali.utils.loadbalance.WeightedRoundRobin;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.List;

/**
 * @description:
 * @author: zhang hang
 * @date: 2022/7/18 16:57.
 * @version: 1.0
 */
@RestController
@Slf4j
public class StockOrderController {

    @Resource
    private IStockOrderService stockOrderService;
    @Resource
    private LoadBalancerClient loadBalancerClient;
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private DiscoveryClient discoveryClient;

    /**
     * description: 注册中心版本 (默认使用轮询的轮询均衡算法)
     *
     * @param id 库存Id
     * @return:
     * @author: zhang hang
     * @date:
     **/
    @GetMapping("/default/getStock/{id}")
    public StockVO getStockDefault(@PathVariable Long id) {
        // 根据你指定的serviceId返回一个具体的服务实例
        ServiceInstance serviceInstance = loadBalancerClient.choose("semptian-stock-service");
        // serviceInstance中就存在这个返回实例的ip和端口
        String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/stock/" + id;
        log.info("【Default】请求的端口号为：{}", serviceInstance.getPort());
        Stock stock = restTemplate.getForObject(url, Stock.class);
        if (stock == null) {
            return null;
        }
        StockVO stockVO = new StockVO();
        BeanUtils.copyProperties(stock, stockVO);
        stockVO.setUrl(url);
        return stockVO;
    }

    /**
     * description: 自定义负载均衡算法
     *
     * @param id 库存Id
     * @return:
     * @author: zhang hang
     * @date:
     **/
    @GetMapping("/custom/getStock/{id}")
    public StockVO getStockCustom(@PathVariable Long id) {
        List<ServiceInstance> instances = discoveryClient.getInstances("sali-stock-service");

        // 简单轮询算法
//        ILoadBalanceAlgorithm loadBalanceAlgorithm = new RoundRobin();
        // 加权轮询算法
//        ILoadBalanceAlgorithm loadBalanceAlgorithm = new WeightedRoundRobin();
        // 平滑加权轮询算法
        ILoadBalanceAlgorithm loadBalanceAlgorithm = new SmoothWeightedRoundRobin();

        ServiceInstance serviceInstance = loadBalanceAlgorithm.algorithmDetail(instances);

        String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/stock/" + id;
        Stock stock = restTemplate.getForObject(url, Stock.class);
        if (stock == null) {
            return null;
        }
        StockVO stockVO = new StockVO();
        BeanUtils.copyProperties(stock, stockVO);
        stockVO.setUrl(url);
        return stockVO;
    }

}
